home *** CD-ROM | disk | FTP | other *** search
/ Euroscene 2 / Euroscene 2.iso / USEFUL / DeliTracker130 / Developer / Developer.run / Examples / TME.s < prev    next >
Encoding:
Text File  |  1992-09-23  |  29.4 KB  |  1,009 lines

  1.  
  2.     incdir    "Includes:"
  3.     include "misc/DeliPlayer.i"
  4.  
  5. ;
  6. ;
  7.     SECTION Player,Code
  8. ;
  9. ;
  10.  
  11.     PLAYERHEADER PlayerTagArray
  12.  
  13.     dc.b '$VER: The Musical Enlightenment player module V1.1 (10 Apr 92)',0
  14.     even
  15.  
  16. PlayerTagArray
  17.     dc.l    DTP_PlayerVersion,1
  18.     dc.l    DTP_PlayerName,PName
  19.     dc.l    DTP_Creator,CName
  20.     dc.l    DTP_Check2,Chk
  21.     dc.l    DTP_Interrupt,Int
  22.     dc.l    DTP_InitPlayer,InitPlay
  23.     dc.l    DTP_EndPlayer,EndPlay
  24.     dc.l    DTP_InitSound,InitSnd
  25.     dc.l    DTP_EndSound,RemSnd
  26.     dc.l    DTP_PrevSong,PrevSub
  27.     dc.l    DTP_NextSong,NextSub
  28.     dc.l    TAG_DONE
  29.  
  30. *-----------------------------------------------------------------------*
  31. ;
  32. ; Player/Creatorname und lokale Daten
  33.  
  34. PName    dc.b 'TME',0
  35. CName    dc.b 'N.J. Luuring jr.,',10
  36.     dc.b 'adapted by Delirium',0
  37.     even
  38.  
  39. Data    dc.l 0
  40.  
  41. *-----------------------------------------------------------------------*
  42. ;
  43. ;Interrupt für Replay
  44.  
  45. Int
  46.     movem.l    d0-d7/a0-a6,-(sp)
  47.     bsr    MUSIC_Player            ; DudelDiDum
  48.     movem.l    (sp)+,d0-d7/a0-a6
  49.     rts
  50.  
  51. *-----------------------------------------------------------------------*
  52. ;
  53. ; Testet auf The_Musical_Enlightenment-Modul
  54.  
  55. Chk
  56.     move.l    dtg_ChkData(a5),a0
  57.  
  58.     move.l    #song_SIZE,d2
  59.     move.w    song_tableentries(a0),d0
  60.     mulu.w    #entr_SIZE,d0
  61.     add.l    d0,d2
  62.     move.w    song_events(a0),d0
  63.     mulu.w    #even_SIZE,d0
  64.     add.l    d0,d2
  65.  
  66.     move.w    #MAXFX-1,d1
  67. Chk_inloop
  68.     add.l    #inuc_SIZE,d2
  69.     cmp.l    dtg_ChkSize(a5),d2
  70.     bgt.s    Chk_fail
  71.     tst.b    inuc_ins-inuc_SIZE(a0,d2.l)
  72.     bne.s    Chk_inloop
  73.     dbra    d1,Chk_inloop
  74.  
  75.     move.w    #MAXINSTR-1,d1
  76.     lea    song_instr(a0),a0
  77. Chk_instl
  78.     tst.b    inst_name(a0)
  79.     beq.s    Chk_nextin
  80.     add.l    inst_sample+samp_len(a0),d2
  81. Chk_nextin
  82.     lea    inst_SIZE(a0),a0
  83.     dbra    d1,Chk_instl
  84.  
  85.     move.l    dtg_ChkSize(a5),d0        ; size of module
  86.     move.l    d0,d1
  87.     sub.l    #$40,d0                ; - 64 Bytes
  88.     add.l    #$40,d1                ; + 64 Bytes
  89.     cmp.l    d0,d2
  90.     blt.s    Chk_fail            ; too small
  91.     cmp.l    d1,d2
  92.     bgt.s    Chk_fail            ; too big
  93.  
  94.     moveq    #0,d0                ; Modul erkannt
  95.     bra.s    ChkEnd
  96. Chk_fail
  97.     moveq    #-1,d0                ; Modul nicht erkannt
  98. ChkEnd
  99.     rts
  100.  
  101. *-----------------------------------------------------------------------*
  102. ;
  103. ; Init Player
  104.  
  105. InitPlay
  106.     moveq    #0,d0
  107.     move.l    dtg_GetListData(a5),a0        ; Function
  108.     jsr    (a0)
  109.     move.l    a0,Data
  110.  
  111.     clr.w    dtg_SndNum(a5)            ; first Subsong
  112.  
  113.     move.l    dtg_AudioAlloc(a5),a0        ; Function
  114.     jsr    (a0)                ; returncode is already set !
  115.     rts
  116.  
  117. *-----------------------------------------------------------------------*
  118. ;
  119. ; End Player
  120.  
  121. EndPlay
  122.     move.l    dtg_AudioFree(a5),a0        ; Function
  123.     jsr    (a0)
  124.     rts
  125.  
  126. *-----------------------------------------------------------------------*
  127. ;
  128. ; Init Sound
  129.  
  130. InitSnd
  131.     move.l    Data,a0
  132.     bsr    MUSIC_InitData            ; Init Sound
  133.     moveq    #0,d0
  134.     move.w    dtg_SndNum(a5),d0
  135.     bsr    MUSIC_Play
  136. InitSndEnd
  137.     rts
  138.  
  139. *-----------------------------------------------------------------------*
  140. ;
  141. ; Remove Sound
  142.  
  143. RemSnd
  144.     bsr    MUSIC_Stop            ; End Sound
  145.     rts
  146.  
  147. *-----------------------------------------------------------------------*
  148. ;
  149. ; Previous SubSong
  150.  
  151. PrevSub
  152.     move.w    dtg_SndNum(a5),d0        ; Vorheriger Sound
  153.     move.l    Data,a0
  154. PrevSubLoop
  155.     tst.w    d0
  156.     beq.s    PrevSubEnd
  157.     subq.w    #1,d0                ; SoundNr. - 1
  158.     move.w    d0,d1
  159.     asl.w    #2,d1
  160.     lea    song_tune(a0,d1.w),a1
  161.     move.b    tune_start(a1),d1
  162.     or.b    tune_end(a1),d1
  163.     beq.s    PrevSubLoop            ; not from 0 to 0 ...
  164.     move.w    d0,dtg_SndNum(a5)        ; SoundNr. sichern
  165.  
  166.     move.l    dtg_StopInt(a5),a0
  167.     jsr    (a0)
  168.     bsr    RemSnd
  169.     bsr    InitSnd
  170.     move.l    dtg_StartInt(a5),a0
  171.     jsr    (a0)                ; Sound An
  172. PrevSubEnd
  173.     rts
  174.     
  175. *-----------------------------------------------------------------------*
  176. ;
  177. ; Next SubSong
  178.  
  179. NextSub
  180.     move.w    dtg_SndNum(a5),d0        ; Nächster Sound
  181.     move.l    Data,a0
  182. NextSubLoop
  183.     addq.w    #1,d0                ; SoundNr. + 1
  184.     cmpi.w    #MAXTUNE,d0
  185.     beq.s    NextSubEnd
  186.     move.w    d0,d1
  187.     asl.w    #2,d1
  188.     lea    song_tune(a0,d1.w),a1
  189.     move.b    tune_start(a1),d1
  190.     or.b    tune_end(a1),d1
  191.     beq.s    NextSubLoop            ; not from 0 to 0 ...
  192.     move.w    d0,dtg_SndNum(a5)        ; SoundNr. sichern
  193.  
  194.     move.l    dtg_StopInt(a5),a0
  195.     jsr    (a0)
  196.     bsr    RemSnd
  197.     bsr    InitSnd
  198.     move.l    dtg_StartInt(a5),a0
  199.     jsr    (a0)                ; Sound An
  200. NextSubEnd
  201.     rts
  202.  
  203. *-----------------------------------------------------------------------*
  204. ;
  205. ; Replay-Routine for TME
  206.  
  207. ***************************************************************************
  208. *                                                                         *
  209. * PLAY - module for Packed TME song-files      (DEVPAC version)           *
  210. *                                                                         *
  211. * Made by N.J.   (1/1/90)                                                 *
  212. *                                                                         *
  213. ***************************************************************************
  214. *                                                                         *
  215. *                                                                         *
  216. * MUSIC_Player   Is a routine to be added to your vertical-blank-handler  *
  217. *                                                                         *
  218. * MUSIC_InitData Can be called when the songdata is loaded/present.       *
  219. *                This must be done before your vertical blank is going !! *
  220. *                A0 must point to the song data (in CHIP_MEM !!)          *
  221. *                                                                         *
  222. * MUSIC_Stop     Must/can be called to (temporarily) stop the player      *
  223. *                                                                         *
  224. * MUSIC_Play     Can be called to start a tune.                           *
  225. *                D0 is the number of the tune to be played.               * 
  226. *                                                                         *
  227. * MUSIC_Continue Can be called to continue a tune after MUSIC_Stop        *
  228. *                                                                         *
  229. * MUSIC_Times    Sets the number of times to play a tune.                 *
  230. *                D0 is this number (0 means forever)                      *
  231. *                                                                         *
  232. ***************************************************************************
  233.  
  234. ;
  235. ;    SECTION    MUSIC
  236. ;
  237.  
  238. ;
  239. ;    INCLUDE    playmodule.i
  240. ;
  241.  
  242. ;*******************************************
  243. ;*                                         *
  244. ;*              STRUCTURES                 *
  245. ;*                                         *
  246. ;*******************************************
  247.  
  248. STRLEN     equ  32
  249. MAXTUNE    equ  16
  250. MAXINSTR   equ  32
  251. MAXFX      equ  256
  252. ARPLEN     equ  9
  253. MAXARPS    equ  64
  254. MAXLFOS    equ  16
  255. LFOLEN     equ  128
  256. TRACKLEN   equ  32
  257. VOICE_OFF  equ  127
  258. RELEASE    equ  126
  259.  
  260. samp_start   equ  0
  261. samp_len     equ  4
  262. samp_stlen   equ  8
  263. samp_restoff equ  12
  264. samp_restlen equ  16
  265. samp_offlen  equ  20
  266. samp_flags   equ  22
  267. samp_SIZE    equ  24
  268.  
  269. tune_start   equ  0
  270. tune_end     equ  1
  271. tune_speed   equ  2
  272. tune_mask    equ  3
  273. tune_SIZE    equ  4
  274.  
  275. inuc_ins   equ 0
  276. inuc_value equ 1
  277. inuc_time  equ 2
  278. inuc_SIZE  equ 4
  279.  
  280. envl_rate  equ 0
  281. envl_level equ 3
  282. envl_SIZE  equ 6
  283.  
  284. even_note   equ 0
  285. even_sample equ 1
  286. even_fx     equ 2
  287. even_vol    equ 3
  288. even_flags  equ 4
  289. even_par    equ 5
  290. even_SIZE   equ 6
  291.  
  292. entr_v0track   equ 0
  293. entr_v0instadd equ 1
  294. entr_v0noteadd equ 2
  295. entr_v1track   equ 3
  296. entr_v1instadd equ 4
  297. entr_v1noteadd equ 5
  298. entr_v2track   equ 6
  299. entr_v2instadd equ 7
  300. entr_v2noteadd equ 8
  301. entr_v3track   equ 9
  302. entr_v3instadd equ 10
  303. entr_v3noteadd equ 11
  304. entr_SIZE      equ 12
  305.  
  306. inst_sample equ 0
  307. inst_name   equ samp_SIZE
  308. inst_volume equ samp_SIZE+STRLEN
  309. inst_eg     equ inst_volume+2
  310. inst_fxmem  equ inst_eg+envl_SIZE
  311. inst_SIZE   equ inst_fxmem+inuc_SIZE*16
  312.  
  313. song_len          equ 0
  314. song_tune         equ song_len+4
  315. song_instr        equ song_tune+tune_SIZE*MAXTUNE
  316. song_arpeggio     equ song_instr+inst_SIZE*MAXINSTR
  317. song_lfo          equ song_arpeggio+MAXARPS*ARPLEN
  318. song_tableentries equ song_lfo+MAXLFOS*LFOLEN
  319. song_events       equ song_tableentries+2
  320. song_instructions equ song_events+2
  321. song_name         equ song_instructions+2
  322. song_SIZE         equ song_name+STRLEN
  323.  
  324. audi_start  equ 0
  325. audi_len    equ 4
  326. audi_period equ 6
  327. audi_volume equ 8
  328. audi_data   equ 10
  329. audi_pad    equ 12
  330. audi_SIZE   equ 16
  331.  
  332. fxda_src        equ 0
  333. fxda_dst        equ 2
  334. fxda_tolevel    equ 4
  335. fxda_level      equ 5
  336. fxda_tospeed    equ 6
  337. fxda_speed      equ 7
  338. fxda_pointer    equ 8
  339. fxda_levelcount equ 12
  340. fxda_speedcount equ 14
  341. fxda_lfo        equ 16
  342. fxda_SIZE       equ 20
  343.  
  344. voic_shadow       equ 0
  345. voic_vibrato      equ audi_SIZE
  346. voic_tremolo      equ voic_vibrato+fxda_SIZE
  347. voic_special      equ voic_tremolo+fxda_SIZE
  348. voic_instr        equ voic_special+fxda_SIZE
  349. voic_event        equ voic_instr+4
  350. voic_insp         equ voic_event+4
  351. voic_egphase      equ voic_insp+4
  352. voic_startphase   equ voic_egphase+2
  353. voic_arpat        equ voic_startphase+2
  354. voic_fxcount      equ voic_arpat+2
  355. voic_gldcount     equ voic_fxcount+2
  356. voic_egcount      equ voic_gldcount+4
  357. voic_toperiod     equ voic_egcount+4
  358. voic_egvolume     equ voic_toperiod+2
  359. voic_basevolume   equ voic_egvolume+2
  360. voic_egtovolume   equ voic_basevolume+2
  361. voic_simplegldadd equ voic_egtovolume+2
  362. voic_dma          equ voic_simplegldadd+2
  363. voic_add          equ voic_dma+2
  364. voic_arpeggio     equ voic_add+4
  365. voic_arplen       equ voic_arpeggio+4
  366. voic_nouse        equ voic_arplen+2
  367. voic_doarpeggio   equ voic_nouse+1
  368. voic_arpblow      equ voic_doarpeggio+1
  369. voic_waitforfx    equ voic_arpblow+1
  370. voic_basearpnote  equ voic_waitforfx+1
  371. voic_arpcount     equ voic_basearpnote+1
  372. voic_arponce      equ voic_arpcount+1
  373. voic_arpspeed     equ voic_arponce+1
  374. voic_SIZE         equ voic_arpspeed+1
  375.  
  376.  
  377. ;*******************************************
  378. ;*                                         *
  379. ;*                DEFINES                  *
  380. ;*                                         *
  381. ;*******************************************
  382.  
  383. BIT_ARPEGGIO    equ 0
  384. BIT_SIMPLEGLIDE equ 1
  385. BIT_NONOTEADD   equ 2
  386. BIT_NOINSTADD   equ 3
  387. BIT_SUPERGLIDE  equ 4
  388. BIT_ARPONCE     equ 5
  389. BIT_ARPBLOW     equ 6
  390.  
  391. ATT_PHASE equ 0
  392. DEC_PHASE equ 1
  393. REL_PHASE equ 2
  394. SUS_PHASE equ 3
  395.  
  396. STARTSAMPLE equ 2
  397. REPSAMPLE   equ 1
  398. KILLSAMPLE  equ 0
  399.  
  400. BIT_SPECIAL equ 0
  401.  
  402. ;    XDEF    MUSIC_Player
  403. ;    XDEF    MUSIC_InitData
  404. ;    XDEF    MUSIC_Stop
  405. ;    XDEF    MUSIC_Play
  406. ;    XDEF    MUSIC_Continue
  407. ;    XDEF    MUSIC_Times
  408.  
  409.  
  410. tune        ds.l    1
  411. firstentry  ds.l    1
  412. lastentry   ds.l    1
  413. entry       ds.l    1
  414. spdcount    ds.l    1
  415. trkcount    ds.l    1
  416. times       ds.l    1
  417. dmacon      ds.w    1
  418. song        ds.l    1
  419. tableentry  ds.l    1
  420. event       ds.l    1
  421. fx          ds.b    inuc_SIZE*MAXFX
  422. voice       ds.b    voic_SIZE*4
  423. NoteTable   dc.w    856,808,762,720,678,640,604,570,538,508,480,453
  424.             dc.w    428,404,381,360,339,320,302,285,269,254,240,226
  425.             dc.w    214,202,190,180,170,160,151,143,135,127,120,113
  426. tabel       dc.w    1,2,1
  427.  
  428.  
  429. ***************************************************************************
  430. *                                                                         *
  431. * NEWTRACK    handles the jump over tracks, pointers are recalculated.    *
  432. *                                                                         *
  433. ***************************************************************************
  434.  
  435. NewTrack
  436.     move.l    #TRACKLEN,trkcount    ; whole track must be done
  437.     move.l    entry,a1        ; A1 is current entry
  438.     lea    voice,a0        ; A0 is voice
  439.     move.l    #3,d1
  440. vloop5    move.l    #0,d0
  441.     move.b    (a1)+,d0
  442.     asl.l    #5,d0            ; Put
  443.     mulu.w    #6,d0            ; track*6 << 5  +  event
  444.     add.l    event,d0        ; into voicedata
  445.     move.l    d0,voic_event(a0)    ; and
  446.     move.l    a1,voic_add(a0)        ; address of add is copied
  447.     add.l    #2,a1
  448.     add.l    #voic_SIZE,a0
  449.     dbra    d1,vloop5
  450.         cmp.l    lastentry,a1
  451.         bne    nstrt            ; Is it the last
  452.         move.l    firstentry,a1        ;   then make first
  453.         sub.l    #1,times        ;   and one less to play
  454. nstrt   move.l    a1,entry        ; store for next time
  455.         rts
  456.  
  457.  
  458. ***************************************************************************
  459. *                                                                         *
  460. * NEWNOTES    handles the new notes, every time the spdcounter reaches 0  *
  461. *                                                                         *
  462. ***************************************************************************
  463.  
  464. NewNotes
  465.     movem.l    a2/a3/a5/a6,-(sp)
  466.     lea    voice,a2            ; a2 is at current voicedata
  467.     lea    NoteTable,a5            ; a5 is at NoteTable
  468.     move.l    tune,a0
  469.     move.l    #0,d3
  470.     move.b    tune_mask(a0),d3        ; d3 is mask for voices
  471.     move.l    #3,d2                ; 4 voices (so dbra from 3)
  472. vloop3    move.l    voic_event(a2),a3        ; a3 is at current event
  473.     move.l    voic_add(a2),a6            ; a6 is at table-adds
  474.     move.l    voic_instr(a2),a1        ; a1 is at instrument
  475.     add.l    #even_SIZE,voic_event(a2)
  476.     tst.b    voic_nouse(a2)            ; is it a superglide-dest ?
  477.     beq    weluse                ;   then next will be used
  478.     clr.b    voic_nouse(a2)            ;   and goto next voice
  479.     bra    nxtv3
  480. weluse    move.b    even_note(a3),d0        ; d0 is (long) note
  481.     and.l    #127,d0                ; is it 0 ?
  482.     beq    nxtv3                ;   then try next voice
  483.     cmp.b    #VOICE_OFF,d0
  484.     bne    voicon                ; is it VOICE_OFF ?
  485.     move.w    voic_dma(a2),d0            ;   then
  486.     and.w    d3,d0                ;   custom.dmacon=mask|dma
  487.     move.w    d0,$dff096            ;   and goto next voice
  488.     bra    nxtv3
  489. voicon    cmp.b    #RELEASE,d0            ; is it RELEASE ?
  490.     bne    norel                ;   then set egphase
  491.     move.w    #REL_PHASE,voic_egphase(a2)
  492.     bra    nxtv3
  493. norel    btst.b    #BIT_NONOTEADD,even_flags(a3)
  494.     bne    noad1
  495.     add.b    1(a6),d0            ; try to add the noteadd
  496. noad1    sub.b    #1,d0                ; is the note not legal ?
  497.     bcs    nxtv3                ;   then try next voice
  498.     move.b    d0,voic_basearpnote(a2)        ; put in basearpnote
  499.     asl.l    #1,d0                ; get period from table
  500.     move.w    (a5,d0.l),voic_vibrato+fxda_src(a2)
  501.     move.l    #0,d0
  502.     btst.b    #BIT_SIMPLEGLIDE,even_flags(a3)
  503.     beq    pokeadd                ; get simpleglide-add in D0
  504.     move.b    even_par(a3),d0
  505.     ext.w    d0
  506. pokeadd    move.w    d0,voic_simplegldadd(a2)
  507.     clr.b    voic_doarpeggio(a2)        ; clear doarpeggio
  508.     move.l    #0,d1
  509.     move.b    even_par(a3),d1            ; get unsigned par in D1
  510.     btst.b    #BIT_SUPERGLIDE,even_flags(a3)
  511.     beq    nosuper                ; is it SUPERGLIDE ?
  512.     move.b    even_SIZE+even_note(a3),d0    ;   get next note
  513.     and.l    #127,d0
  514.     btst.b    #BIT_NONOTEADD,even_flags(a3)    ;   and add
  515.     bne    noadd2
  516.     add.b    1(a6),d0
  517. noadd2    sub.b    #1,d0                ;   is note not legal ?
  518.     bcs    clrgld                ;   then no glide, no arp
  519.     asl.l    #1,d0
  520.     move.w    (a5,d0.l),voic_toperiod(a2)    ;   get period
  521.     add.l    #1,d1
  522.     move.l    d1,voic_gldcount(a2)        ;   glidecount is par+1
  523.     move.b    #1,voic_nouse(a2)        ;   next note is not used
  524.     bra    noarp
  525. nosuper    btst.b    #BIT_ARPEGGIO,even_flags(a3)    ; is it ARPEGGIO ?
  526.     beq    clrgld                ;   then
  527.     clr.b    voic_arponce(a2)        ;   get ARPONCE-value
  528.     btst.b    #BIT_ARPONCE,even_flags(a3)    ;   (1 when once)
  529.     beq    notonce
  530.     move.b    #1,voic_arponce(a2)
  531. notonce    move.b    even_flags(a3),d0        ;   get ARPBLOW-tstvalue
  532.     and.b    #64,d0
  533.     move.b    d0,voic_arpblow(a2)
  534.     mulu.w    #ARPLEN,d1
  535.     move.l    song,a0
  536.     add.l    #song_arpeggio+1,a0        ;   get start of arpeggio
  537.     add.l    d1,a0
  538.     move.l    a0,voic_arpeggio(a2)
  539.     move.b    -1(a0),d0            ;   before this stands
  540.     move.l    #0,d1                ;   - len<<4|speed -
  541.     move.b    d0,d1
  542.     and.b    #15,d0
  543.     move.b    d0,voic_arpspeed(a2)        ;   get speed
  544.     add.b    #1,d0                ;   for the  first:
  545.     move.b    d0,voic_arpcount(a2)        ;   count = speed + 1
  546.     lsr.w    #4,d1
  547.     bne    pokelen
  548.     move.l    #8,d1                ;   default len is 8
  549. pokelen    move.w    d1,voic_arplen(a2)        ;   poke len
  550.     sub.w    #1,d1
  551.     move.b    d1,voic_doarpeggio(a2)        ;   doarpeggio is len-1
  552.     clr.w    voic_arpat(a2)            ;   start at begin of arp
  553. clrgld    clr.l    voic_gldcount(a2)        ;   no glide here
  554. noarp    btst.b    #7,even_note(a3)
  555.     bne    noblow                ; is the note blown ?
  556.     clr.w    voic_egphase(a2)        ;   then
  557.     clr.w    voic_egvolume(a2)        ;   set new EG-values
  558.     clr.l    voic_egcount(a2)        ;   and sample-phase
  559.     move.w    #STARTSAMPLE,voic_startphase(a2)
  560.     move.l    #0,d0
  561.     move.b    even_sample(a3),d0
  562.     beq    samein                ;   a new instrument ?
  563.     sub.b    #1,d0                ;     then
  564.     btst.b    #BIT_NOINSTADD,even_flags(a3)    ;     get instr-no
  565.     bne    noadd3                ;          (plus add)
  566.     add.b    (a6),d0
  567.     and.b    #$1f,d0                ;     (ensure legality)
  568. noadd3    asl.l    #7,d0
  569.     move.l    song,a1
  570.     add.l    #song_instr,a1            ;     to instr-pointer
  571.     add.l    d0,a1                ;     into A1
  572.     move.l    a1,voic_instr(a2)        ;     and the structure
  573. samein    move.w    voic_dma(a2),d0
  574.     and.w    d3,d0                ;   clr custom.dmacon,
  575.     or.w    d0,dmacon            ;   and prepare to set
  576.     move.w    d0,$dff096
  577.     move.l    #0,d0
  578.     move.b    even_fx(a3),d0            ;   get fx-pointer
  579.     beq    deffx
  580.     asl.l    #2,d0                ;   non-default is from
  581.     lea    fx,a0                ;   the song structure
  582.     move.l    (a0,d0.l),a0
  583.     bra    pokefx                ;   default comes from
  584. deffx    lea    inst_fxmem(a1),a0        ;   the instrument
  585. pokefx    move.l    a0,voic_insp(a2)
  586.     clr.b    voic_vibrato+fxda_level(a2)    ;   clear all fx-levels
  587.     clr.b    voic_vibrato+fxda_speed(a2)    ;   and fx-speeds
  588.     clr.b    voic_tremolo+fxda_level(a2)
  589.     clr.b    voic_tremolo+fxda_speed(a2)
  590.     clr.b    voic_special+fxda_level(a2)
  591.     clr.b    voic_special+fxda_speed(a2)
  592.     clr.l    voic_vibrato+fxda_pointer(a2)
  593.     clr.l    voic_tremolo+fxda_pointer(a2)
  594.     clr.l    voic_special+fxda_pointer(a2)    ;   let TryNewFx do it...
  595.     move.b    #1,voic_waitforfx(a2)        ;   we are ready with waiting
  596.     clr.w    voic_fxcount(a2)
  597. noblow    move.b    inst_volume(a1),d0        ; get instr-volume
  598.     add.b    even_vol(a3),d0            ; and add the volume-add
  599.     ext.w    d0                ; into the basevolume
  600.     move.w    d0,voic_basevolume(a2)
  601. nxtv3    add.l    #voic_SIZE,a2            ; next voicedata
  602.     dbra    d2,vloop3            ; go again until all 4 voices
  603.     movem.l    (sp)+,a2/a3/a5/a6        ; are done
  604.     rts
  605.  
  606.  
  607. ***************************************************************************
  608. *                                                                         *
  609. * TRYNEWFX    walks over the fx, every time the fxcounter reaches 0       *
  610. *                                                                         *
  611. ***************************************************************************
  612.  
  613. TryNewFx
  614.     movem.l    a2/a3,-(sp)
  615.     lea    voice,a2            ; A2 is at voicedata
  616.     move.l    song,a1
  617.     add.l    #song_lfo,a1            ; A1 is at lfo
  618.     move.l    #3,d3
  619. vloop4    tst.b    voic_waitforfx(a2)        ; are we waiting ?
  620.     beq    nxtv4                ;   if not then next voice
  621.     sub.w    #1,voic_fxcount(a2)        ;   dec fxcount
  622.     bcc    nxtv4                ;   if not ready then next
  623.     move.l    voic_insp(a2),a3        ;   A3 is instruction-pointer
  624. iloop    move.b    inuc_ins(a3),d0
  625.     and.l    #$f0,d0
  626.     lsr.l    #3,d0                ;   instruction in D0
  627.     move.w    jmptab(pc,d0.w),d0        ;   get jump-offset
  628. jmpfrom    jmp    jmpfrom(pc,d0.w)        ;   jump to right routine
  629. nxtv4    add.l    #voic_SIZE,a2            ;   get next voicedata
  630.     dbra    d3,vloop4            ;   for all 4 voices
  631.     movem.l    (sp)+,a2/a3
  632.     rts
  633. jmptab    dc.w    stop-jmpfrom            ; 0 = STOP
  634.     dc.w    vlev-jmpfrom            ; 1 = VIBRATO.level
  635.     dc.w    vspd-jmpfrom            ; 2 = VIBRATO.speed
  636.     dc.w    tlev-jmpfrom            ; 3 = TREMOLO.level
  637.     dc.w    tspd-jmpfrom            ; 4 = TREMOLO.speed
  638.     dc.w    slev-jmpfrom            ; 5 = SPECIAL.level
  639.     dc.w    sspd-jmpfrom            ; 6 = SPECIAL.speed
  640.     dc.w    dela-jmpfrom            ; 7 = DELAY
  641.     dc.w    goto-jmpfrom            ; 8 = GOTO
  642. stop    clr.b    voic_waitforfx(a2)
  643.     bra    nxtv4
  644. vlev    move.b    inuc_value(a3),voic_vibrato+fxda_tolevel(a2)
  645.     move.w    inuc_time(a3),voic_vibrato+fxda_levelcount(a2)
  646.     add.w    #1,voic_vibrato+fxda_levelcount(a2)
  647.     move.b    inuc_ins(a3),d0
  648.     and.l    #15,d0
  649.     asl.l    #7,d0
  650.     add.l    a1,d0
  651.     move.l    d0,voic_vibrato+fxda_lfo(a2)
  652.     add.l    #inuc_SIZE,a3
  653.     bra    iloop
  654. vspd    move.b    inuc_value(a3),voic_vibrato+fxda_tospeed(a2)
  655.     move.w    inuc_time(a3),voic_vibrato+fxda_speedcount(a2)
  656.     add.w    #1,voic_vibrato+fxda_speedcount(a2)
  657.     add.l    #inuc_SIZE,a3
  658.     bra    iloop
  659. tlev    move.b    inuc_value(a3),voic_tremolo+fxda_tolevel(a2)
  660.     move.w    inuc_time(a3),voic_tremolo+fxda_levelcount(a2)
  661.     add.w    #1,voic_tremolo+fxda_levelcount(a2)
  662.     move.b    inuc_ins(a3),d0
  663.     and.l    #15,d0
  664.     asl.l    #7,d0
  665.     add.l    a1,d0
  666.     move.l    d0,voic_tremolo+fxda_lfo(a2)
  667.     add.l    #inuc_SIZE,a3
  668.     bra    iloop
  669. tspd    move.b    inuc_value(a3),voic_tremolo+fxda_tospeed(a2)
  670.     move.w    inuc_time(a3),voic_tremolo+fxda_speedcount(a2)
  671.     add.w    #1,voic_tremolo+fxda_speedcount(a2)
  672.     add.l    #inuc_SIZE,a3
  673.     bra    iloop
  674. slev    move.b    inuc_value(a3),voic_special+fxda_tolevel(a2)
  675.     move.w    inuc_time(a3),voic_special+fxda_levelcount(a2)
  676.     add.w    #1,voic_special+fxda_levelcount(a2)
  677.     move.b    inuc_ins(a3),d0
  678.     and.l    #15,d0
  679.     asl.l    #7,d0
  680.     add.l    a1,d0
  681.     move.l    d0,voic_special+fxda_lfo(a2)
  682.     add.l    #inuc_SIZE,a3
  683.     bra    iloop
  684. sspd    move.b    inuc_value(a3),voic_special+fxda_tospeed(a2)
  685.     move.w    inuc_time(a3),voic_special+fxda_speedcount(a2)
  686.     add.w    #1,voic_special+fxda_speedcount(a2)
  687.     add.l    #inuc_SIZE,a3
  688.     bra    iloop
  689. dela    move.w    inuc_time(a3),voic_fxcount(a2)
  690.     add.l    #inuc_SIZE,a3
  691.     move.l    a3,voic_insp(a2)
  692.     bra    nxtv4
  693. goto    move.l    #0,d0
  694.     move.b    inuc_value(a3),d0
  695.     asl.l    #2,d0
  696.     lea    fx,a0
  697.     move.l    (a0,d0.l),a3
  698.     bra    iloop
  699.  
  700.  
  701. ***************************************************************************
  702. *                                                                         *
  703. * CALCFXDATA  calculates vibrato/tremolo fxvalues, every frame 3x         *
  704. *                                                                         *
  705. ***************************************************************************
  706.  
  707. CalcFxData
  708.     move.b    fxda_tolevel(a1),d0    ; are we going somewhere ?
  709.     beq    jcopy            ; if not then just copy src to dst
  710.     tst.w    fxda_levelcount(a1)
  711.     beq    levred            ; is level not yet OK ?
  712.     sub.b    fxda_level(a1),d0    ;   then get difference with tolevel
  713.     ext.w    d0            ;   into long
  714.     ext.l    d0
  715.     divs.w    fxda_levelcount(a1),d0    ;   and part of it
  716.     add.b    d0,fxda_level(a1)    ;   must be added to the level
  717.     sub.w    #1,fxda_levelcount(a1)    ;   (less to go)
  718. levred    tst.w    fxda_speedcount(a1)
  719.     beq    spdred            ; is speed not yet OK ?
  720.     move.b    fxda_tospeed(a1),d0    ;   then get difference from
  721.     sub.b    fxda_speed(a1),d0    ;   tospeed and speed
  722.     ext.w    d0            ;   into long
  723.     ext.l    d0
  724.     divs.w    fxda_speedcount(a1),d0    ;   and part of it
  725.     add.b    d0,fxda_speed(a1)    ;   must be added to speed
  726.     sub.w    #1,fxda_speedcount(a1)    ;   (less to go)
  727. spdred    move.l    fxda_pointer(a1),d1
  728.     move.l    fxda_lfo(a1),a0
  729.     move.b    (a0,d1.l),d0        ; get current lfo-value
  730.     ext.w    d0            ; into word D0
  731.     move.l    #0,d1
  732.     move.b    fxda_level(a1),d1    ; multiply
  733.     muls.w    d1,d0            ; with unsigned word-level
  734.     lsr.l    d2,d0            ; shift by second parameter
  735.     add.w    fxda_src(a1),d0        ; and add source to it
  736.     move.w    d0,fxda_dst(a1)        ; into destination
  737.     move.b    fxda_speed(a1),d0    
  738.     add.b    d0,fxda_pointer+3(a1)    ; add speed to pointer
  739.     and.l    #127,fxda_pointer(a1)    ; keep it within range
  740.     rts
  741. jcopy    move.w    fxda_src(a1),fxda_dst(a1)
  742.     rts
  743.  
  744.  
  745. ***************************************************************************
  746. *                                                                         *
  747. * CALCFX      calculates all (new) dma-values, every frame again          *
  748. *                                                                         *
  749. ***************************************************************************
  750.  
  751. CalcFx
  752.     movem.l    d5/a2/a3/a5/a6,-(sp)
  753.     lea    voice,a2            ; A2 is at voicedata
  754.     lea    NoteTable,a5            ; A5 is at NoteTable
  755.     lea    tabel,a6            ; A6 is at phase-add table
  756.     move.l    tune,a0
  757.     move.l    #0,d3
  758.     move.b    tune_mask(a0),d3        ; D3 is mask
  759.     move.l    #3,d5
  760. vloop1    move.l    voic_instr(a2),a3        ; A3 is at instrument
  761.     move.w    voic_simplegldadd(a2),d0    ; add simplegldadd
  762.     add.w    d0,voic_vibrato+fxda_src(a2)    ; to vibrato.src
  763.     move.l    voic_gldcount(a2),d1
  764.     beq    nogld
  765.     move.l    #0,d0                ; do we have SUPERGLIDE ?
  766.     move.l    #0,d2                ;   then
  767.     move.w    voic_toperiod(a2),d0        ;   get difference of
  768.     move.w    voic_vibrato+fxda_src(a2),d2    ;   unsigned values
  769.     sub.l    d2,d0                ;   and part of it
  770.     divs.w    d1,d0                ;   is added to the
  771.     add.w    d0,voic_vibrato+fxda_src(a2)    ;   vibrato.src
  772.     sub.l    #1,voic_gldcount(a2)        ;   (less to go)
  773.     bra    dovibr                ;   no arpeggio...
  774. nogld    tst.b    voic_doarpeggio(a2)
  775.     beq    dovibr                ; do we have ARPEGGIO ?
  776.     move.l    #0,d0                ;   then
  777.     move.w    voic_arpat(a2),d1        ;   get pointer in D1
  778.     sub.b    #1,voic_arpcount(a2)        ;   switch to next arpnote ?
  779.     bcc    hanarp                ;     then
  780.     add.w    #1,d1                ;     move pointer
  781.     divu.w    voic_arplen(a2),d1        ;     through arpeggio
  782.     swap    d1                ;     (MOD arplen)
  783.     move.w    d1,voic_arpat(a2)
  784.     move.b    voic_arpspeed(a2),voic_arpcount(a2)
  785.     move.b    voic_arponce(a2),d0        ;     reset counter
  786.     sub.b    d0,voic_doarpeggio(a2)        ;     (dec doarpeggio)
  787.     tst.b    voic_arpblow(a2)
  788.     beq    hanarp                ;     should arp be blown ?
  789.     move.w    #STARTSAMPLE,voic_startphase(a2);       then
  790.     clr.w    voic_egphase(a2)        ;       set startphase
  791.     clr.l    voic_egcount(a2)        ;       set new EG-values
  792.     clr.w    voic_egvolume(a2)        ;       and clr dmabit
  793.     move.w    voic_dma(a2),d0            ;       (prepare for set)
  794.     and.w    d3,d0
  795.     or.w    d0,dmacon
  796.     move.w    d0,$dff096            ;   and
  797. hanarp    move.b    voic_basearpnote(a2),d0        ;   Handle ARPEGGIO-period
  798.     move.l    voic_arpeggio(a2),a0
  799.     add.b    (a0,d1.w),d0
  800.     asl.l    #1,d0
  801.     move.w    (a5,d0.l),voic_vibrato+fxda_src(a2)
  802. dovibr    move.l    #7,d2                ; Calc vibrato with
  803.     lea    voic_vibrato(a2),a1        ; shift is 7
  804.     bsr    CalcFxData
  805.     move.w    voic_vibrato+fxda_dst(a2),d0
  806.     cmp.w    #113,d0
  807.     bge    okper
  808.     move.w    #113,d0                ; set period to minimum
  809. okper    move.w    d0,voic_shadow+audi_period(a2)    ; of 113
  810.     move.l    voic_egcount(a2),d1
  811.     beq    newpha                ; busy in EG-phase ?
  812.     move.l    #0,d0                ;   then
  813.     move.l    #0,d2                ;   get difference of
  814.     move.w    voic_egtovolume(a2),d0        ;   unsigned values
  815.     move.w    voic_egvolume(a2),d2        ;   and add
  816.     sub.l    d2,d0                ;   part of it
  817.     divs.w    d1,d0                ;   to the current volume
  818.     add.w    d0,voic_egvolume(a2)        ;   (less to go)
  819.     sub.l    #1,voic_egcount(a2)
  820.     bra    nocha                ;   else
  821. newpha    move.w    voic_egphase(a2),d2        ;   D2 is egphase
  822.     cmp.l    #SUS_PHASE,d2            ;   is it in SUSTAIN ?
  823.     beq    nocha                ;     then nothing changes
  824.     move.l    #0,d0
  825.     move.b    inst_eg+envl_rate(a3,d2.w),d0
  826.     add.l    #1,d0                ;   egcount    := rate + 1
  827.     move.l    d0,voic_egcount(a2)        ;   egtovolume := level
  828.     move.b    inst_eg+envl_level(a3,d2.w),voic_egtovolume+1(a2)
  829.     asl.w    #1,d2                ;   get next egphase
  830.     move.w    (a6,d2.w),d1            ;   with adds-tabel
  831.     add.w    d1,voic_egphase(a2)
  832. nocha    move.w    voic_basevolume(a2),d0
  833.     muls.w    voic_egvolume(a2),d0        ; get src-volume
  834.     asr.w    #8,d0                ; from base- and egvolume
  835.     move.w    d0,voic_tremolo+fxda_src(a2)    ; and calc the tremolo
  836.     move.l    #9,d2                ; with shift 9
  837.     lea    voic_tremolo(a2),a1
  838.     bsr    CalcFxData
  839.     move.w    voic_tremolo+fxda_dst(a2),d0
  840.     cmp.w    #64,d0
  841.     ble    okvol                ; maximize volume to 64
  842.     move.l    #64,d0
  843. okvol    move.w    d0,voic_shadow+audi_volume(a2)
  844.     tst.w    voic_startphase(a2)        ; get start and length
  845.     beq    nxtv1                ; according to current
  846.     cmp.w    #STARTSAMPLE,voic_startphase(a2); startphase
  847.     bne    repsam
  848.     move.l    inst_sample+samp_start(a3),voic_shadow+audi_start(a2)
  849.     move.w    inst_sample+samp_stlen+2(a3),voic_shadow+audi_len(a2)
  850.     move.w    #1,voic_startphase(a2)
  851.     bra    nxtv1
  852. repsam    move.l    inst_sample+samp_start(a3),voic_shadow+audi_start(a2)
  853.     move.l    inst_sample+samp_restoff(a3),d0
  854.     asl.l    #1,d0
  855.     add.l    d0,voic_shadow+audi_start(a2)
  856.     move.w    inst_sample+samp_restlen+2(a3),voic_shadow+audi_len(a2)
  857.     clr.w    voic_startphase(a2)
  858. nxtv1    add.l    #voic_SIZE,a2
  859.     dbra    d5,vloop1
  860.     movem.l    (sp)+,d5/a2/a3/a5/a6
  861.     rts
  862.  
  863.  
  864. ***************************************************************************
  865. *                                                                         *
  866. * GLOBAL routines                                                         *
  867. *                                                                         *
  868. ***************************************************************************
  869.  
  870. MUSIC_Player
  871.     movem.l    d4/a2,-(sp)
  872.     move.l    times,d0
  873.     beq    return            ; if !times return (no play).
  874.     move.l    tune,a2            ; A2 is at tune
  875.     move.l    #0,d4            ; D4 is mask
  876.     move.b    tune_mask(a2),d4
  877.     tst.w    dmacon
  878.     beq    nodma            ; must we set some bits ?
  879.     move.w    dmacon,d0        ;   then
  880.     or.w    #$8200,d0        ;   set them
  881.     move.w    d0,$dff096        ;   (already masked)
  882.     clr.w    dmacon
  883. nodma    sub.b    #1,spdcount        ; time for new notes ?
  884.     bcc    nonewno            ;   then
  885.     move.b    2(a2),spdcount        ;   reset spdcount
  886.     sub.l    #1,trkcount        ;   time for new track ?
  887.     bne    nonewtr
  888.     bsr    NewTrack        ;     then New Track
  889. nonewtr    bsr    NewNotes        ;   New Notes
  890. nonewno    bsr    TryNewFx        ; walk through fx
  891.     bsr    CalcFx            ; calc all dma-values
  892.     move.l    #3,d1
  893.     lea    voice,a0        ; A0 is at voicedata
  894.     move.l    #$dff0a0,a1        ; A1 is at hardware-audio
  895. vloop2    move.w    d4,d0            ; if mask is set ?
  896.     and.w    voic_dma(a0),d0        ;   then poke dma-values
  897.     beq    nxtv2
  898.     move.l    voic_shadow+audi_start(a0),audi_start(a1)
  899.     move.w    voic_shadow+audi_len(a0),audi_len(a1)
  900.     move.w    voic_shadow+audi_period(a0),audi_period(a1)
  901.     move.w    voic_shadow+audi_volume(a0),audi_volume(a1)
  902. nxtv2    add.l    #voic_SIZE,a0        ; get next voicedata
  903.     add.l    #audi_SIZE,a1        ; and next audio-channel
  904.     dbra    d1,vloop2        ; until all voices are done
  905. return    movem.l    (sp)+,d4/a2
  906.     rts
  907.  
  908. MUSIC_InitData
  909.     move.w    #255,$dff09e
  910.     move.l    a0,song            ; ->  Song structure
  911.     move.l    a0,a1
  912.     add.l    #song_SIZE,a0
  913.     move.l    a0,tableentry        ; ->  TableEntries
  914.     move.w    song_tableentries(a1),d0
  915.     mulu.w    #entr_SIZE,d0
  916.     add.l    d0,a0
  917.     move.l    a0,event        ; ->  Events
  918.     move.w    song_events(a1),d0
  919.     mulu.w    #even_SIZE,d0
  920.     add.l    d0,a0
  921.     move.l    #0,d1
  922.     lea    fx,a1            ; ->  Fx
  923. fxloop    move.l    a0,(a1,d1.l)
  924. inloop    add.l    #inuc_SIZE,a0
  925.     tst.b    inuc_ins-inuc_SIZE(a0)
  926.     bne    inloop
  927.     add.l    #inuc_SIZE,d1
  928.     cmp.l    #inuc_SIZE*MAXFX,d1
  929.     blt    fxloop
  930.     move.l    #0,d1
  931.     move.l    song,a1
  932.     add.l    #song_instr,a1
  933. instl    tst.b    inst_name(a1,d1.l)    ; -> Sample Data
  934.     beq    nextin
  935.     move.l    a0,inst_sample+samp_start(a1,d1.l)
  936.     add.l    inst_sample+samp_len(a1,d1.l),a0
  937. nextin    add.l    #inst_SIZE,d1
  938.     cmp.l    #inst_SIZE*MAXINSTR,d1
  939.     blt    instl
  940.  
  941. MUSIC_Stop
  942.     move.l    #0,times        ; no playing,
  943.     move.w    #15,$dff096        ; clear dma
  944. ;    bclr    #1,$bfe001        ; and LED on
  945.     clr.w    dmacon
  946.     rts
  947.  
  948. MUSIC_Play
  949.     asl.l    #2,d0
  950.     move.l    song,a1
  951.     add    #song_tune,a1
  952.     add.l    d0,a1
  953.     move.l    a1,tune            ; get pointer to current tune
  954.     bsr    MUSIC_Stop        ; and stop the music
  955.     move.b    tune_start(a1),d0
  956.     or.b    tune_end(a1),d0
  957.     bne    normal            ; not from 0 to 0 ...
  958.     rts
  959. normal    move.l    #0,d0
  960.     move.b    tune_start(a1),d0
  961.     mulu.w    #entr_SIZE,d0
  962.     add.l    tableentry,d0
  963.     move.l    d0,firstentry        ; set first,
  964.     move.l    #0,d0            ; and lastentry
  965.     move.b    tune_end(a1),d0
  966.     mulu.w    #entr_SIZE,d0
  967.     add.l    tableentry,d0
  968.     move.l    d0,lastentry
  969.     move.w    #1,voice+voic_SIZE*0+voic_dma
  970.     move.w    #2,voice+voic_SIZE*1+voic_dma
  971.     move.w    #4,voice+voic_SIZE*2+voic_dma
  972.     move.w    #8,voice+voic_SIZE*3+voic_dma
  973.     move.w    #0,voice+voic_SIZE*0+voic_egtovolume
  974.     move.w    #0,voice+voic_SIZE*1+voic_egtovolume
  975.     move.w    #0,voice+voic_SIZE*2+voic_egtovolume
  976.     move.w    #0,voice+voic_SIZE*3+voic_egtovolume
  977.     move.l    firstentry,d0
  978.     add.l    #entr_SIZE,d0
  979.     move.l    d0,entry        ; entry is firstentry+1
  980.  
  981. MUSIC_Continue
  982.     bsr    MUSIC_Stop        ; first stop the music
  983.     move.l    tune,a0            ; set new spdcount
  984.     clr.l    spdcount
  985.     move.b    tune_speed(a0),spdcount+3
  986.     move.l    entry,a0
  987.     cmp.l    firstentry,a0        ; go back one entry
  988.     bne    okentr
  989.     move.l    lastentry,a0
  990. okentr    sub.l    #entr_SIZE,a0
  991.     move.l    a0,entry
  992.     bsr    NewTrack        ; and prepare for this track
  993.     add.l    #1,trkcount
  994.     move.l    tune,a1
  995. ;    btst.b    #4,tune_mask(a1)    ; handle LED for this tune
  996. ;    beq    ledon
  997. ;    bset    #1,$bfe001
  998. ;    bra    okled
  999. ;ledon    bclr    #1,$bfe001
  1000. okled    move.l    #$ffffffff,times    ; START play endlessly
  1001.     rts
  1002.  
  1003. MUSIC_Times
  1004.     tst.l    d0
  1005.     bne    oktime
  1006.     move.l    #$ffffffff,d0
  1007. oktime    move.l    d0,times
  1008.     rts
  1009.